#include "smart-device-database.h"

SmartDeviceDatabase *SmartDeviceDatabase::db = new SmartDeviceDatabase;

SmartDeviceDatabase *SmartDeviceDatabase::getSmartDeviceDatabase()
{
    return db;
}

bool SmartDeviceDatabase::addDevice(const string &operation, const string &deviceType, const string &deviceNumber)
{
    sqlite3_bind_text(add_stmt, 1, operation.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(add_stmt, 2, deviceType.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(add_stmt, 3, deviceNumber.c_str(), -1, SQLITE_STATIC);
    int ret = sqlite3_step(add_stmt);
    sqlite3_reset(add_stmt);
    if (ret != SQLITE_DONE)
    {
        fprintf(stderr, "Fail to sqlite3_step error code: %d\n", ret);
        return false;
    }
    return true;
}

bool SmartDeviceDatabase::removeDevice(const string &operation, const string &deviceType, const string &deviceNumber)
{
    sqlite3_bind_text(remove_stmt, 1, operation.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(remove_stmt, 2, deviceType.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(remove_stmt, 3, deviceNumber.c_str(), -1, SQLITE_STATIC);
    int ret = sqlite3_step(remove_stmt);
    sqlite3_reset(remove_stmt);
    if (ret != SQLITE_DONE)
    {
        fprintf(stderr, "Fail to sqlite3_step error code: %d\n", ret);
        return false;
    }
    return true;
}

vector<smart_device_t> SmartDeviceDatabase::queryDevice(bool *ok)
{
    vector<smart_device_t> smartDeviceVector;
    smart_device_t smartDevice;

    while (1)
    {
        int ret = sqlite3_step(query_stmt);
        if (ret == SQLITE_DONE)
        {
            break; // 执行完成
        }
        else if (ret == SQLITE_ROW)
        {
            smartDevice.operation = (char *)sqlite3_column_text(query_stmt, 0);
            smartDevice.deviceType = (char *)sqlite3_column_text(query_stmt, 1);
            smartDevice.deviceNumber = (char *)sqlite3_column_text(query_stmt, 2);
            smartDeviceVector.push_back(smartDevice);
        }
        else
        {
            if (ok)
            {
                *ok = false;
            }
            fprintf(stderr, "Fail to sqlite3_step,err code%d\n", ret);
            break;
        }
    }

    if (ok)
    {
        *ok = true;
    }

    return smartDeviceVector;
}

SmartDeviceDatabase::SmartDeviceDatabase()
{
    int ret = sqlite3_open("smart_device.db", &pdb);
    if (ret != SQLITE_OK)
    {
        fprintf(stderr, "Fail to sqlite3_open smart_device.db%s\n", sqlite3_errmsg(pdb));
        return;
    }

    char *errmsg;
    const char *sql = "create table if not exists smart_device(operation,deviceType,deviceNumber,primary key(operation,deviceType,deviceNumber))";
    ret = sqlite3_exec(pdb, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        fprintf(stderr, "Fail to sqlite_exec %s:%s\n", sql, errmsg);
        return;
    }

    const char *add_sql = "insert into smart_device values(?,?,?)";
    ret = sqlite3_prepare(pdb, add_sql, -1, &add_stmt, NULL);
    if (ret != SQLITE_OK)
    {
        fprintf(stderr, "Fail to sqlite3_prepare %s:%s\n", add_sql, errmsg);
        return;
    }

    const char *remove_sql = "delete from smart_device where operation=? and deviceType=? and deviceNumber=?";
    ret = sqlite3_prepare(pdb, remove_sql, -1, &remove_stmt, NULL);
    if (ret != SQLITE_OK)
    {
        fprintf(stderr, "Fail to sqlite3_prepare %s:%s\n", remove_sql, errmsg);
        return;
    }

    const char *query_sql = "select * from smart_device;";
    ret = sqlite3_prepare(pdb, query_sql, -1, &query_stmt, NULL);
    if (ret != SQLITE_OK)
    {
        fprintf(stderr, "Fail to sqlite3_prepare %s:%s\n", query_sql, errmsg);
        return;
    }
}

SmartDeviceDatabase::~SmartDeviceDatabase()
{
    sqlite3_finalize(add_stmt);
    sqlite3_finalize(remove_stmt);
    sqlite3_finalize(query_stmt);
    sqlite3_close(pdb);
}
